package com.jh.paymentchannel.service;

import cn.jh.common.utils.CommonConstants;
import cn.jh.common.utils.UUIDGenerator;
import com.jh.paymentchannel.business.AutomaticRepaymentTaskBusiness;
import com.jh.paymentchannel.helipay.service.HLRegisterService;
import com.jh.paymentchannel.helipay.service.QuickPayApi;
import com.jh.paymentchannel.pojo.AutomaticRepaymentTask;
import com.jh.paymentchannel.pojo.NumberCheck;
import com.jh.paymentchannel.util.Util;
import net.sf.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static org.springframework.util.StringUtils.hasText;


@Controller
public class AutomaticRepaymentTaskService {
    private static final Logger LOG = LoggerFactory.getLogger(AutomaticRepaymentTaskService.class);

    @Autowired
    AutomaticRepaymentTaskBusiness automaticRepaymentTask;
    @Autowired
    Util util;
    @Autowired
    HLRegisterService hlr;
    @Autowired
    SpendService ss;
    @Autowired
    QuickPayApi qp;

    @RequestMapping(method = RequestMethod.POST, value = "/v1.0/paymentchannel/automaticrepaymenttask/add")
    public @ResponseBody
    Object addAutomaticRepaymentTask(
            HttpServletRequest request,
            @RequestParam(value = "orderCode", required = false) String orderCode,
            @RequestParam(value = "realAmount", required = false) String realAmount,
            @RequestParam(value = "singleFee", required = false) String singleFee,
            @RequestParam(value = "status", required = false) String status,
            @RequestParam(value = "batchNo", required = false) String batchNo,
            @RequestParam(value = "type", required = false) String type,
            @RequestParam(value = "payCard", required = false) String payCard,
            @RequestParam(value = "userId") String userId, @RequestParam(value = "bindId") String bindId,
            @RequestParam(value = "rate") String rate, @RequestParam(value = "amount") String amount,
            @RequestParam(value = "executionTime") String executionTime) {
        Map<String, Object> map = new HashMap<>();

        AutomaticRepaymentTask model = new AutomaticRepaymentTask();
        orderCode = UUIDGenerator.getUUID();
        model.setOrderCode(orderCode);
        model.setUserId(Integer.valueOf(userId));
        model.setBindId(bindId);
        model.setType(type);
        model.setStatus(status);
        if (null != singleFee && !"".equals(singleFee))
            model.setSingleFee(new BigDecimal(singleFee));
        if (Float.valueOf(rate) < Float.valueOf("0.0047")) {
            map.put(CommonConstants.RESP_CODE, CommonConstants.ERROR_PARAM);
            map.put(CommonConstants.RESP_MESSAGE, "费率异常，请联系客服！");
            return map;
        }
        if (payCard != null && !payCard.equals(""))
            model.setPayCard(payCard);
        if (batchNo != null && !batchNo.equals(""))
            model.setBatchNo(batchNo);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
        try {
            model.setExecutionTime(sdf.parse(executionTime));
            model.setRate(new BigDecimal(rate));
            if (!"".equals(realAmount) && realAmount != null) {
                model.setRealAmount(new BigDecimal(realAmount));
            }
            model.setAmount(new BigDecimal(amount));
        } catch (Exception e) {
            LOG.error(e.toString());
            map.put(CommonConstants.RESP_CODE, CommonConstants.ERROR_PARAM);
            map.put(CommonConstants.RESP_MESSAGE, "添加失败,参数转换异常");
            return map;
        }
        model.setCreateTime(new Date());

        try {
            model = automaticRepaymentTask.addAutomaticRepaymentTask(model);
            int num = amount.indexOf(".");
            double littleBalance = Double.parseDouble("0." + amount.substring(num + 1, amount.length()));//小数金额
            String amountZ = amount.substring(0, num);//去掉小数金额
            int surplus = Integer.valueOf(amountZ) % 2;//整除余数
            int amountEll = Integer.valueOf(amountZ) - surplus;
            int amountE = (int) ((double) amountEll / 2);
            amountE = amountE + (int) (Math.random() * (amountE - 5));
            int amountEEE = amountEll - amountE;
            DecimalFormat decimalFormat = new DecimalFormat("0.00");
            decimalFormat.setRoundingMode(RoundingMode.UP);
            if (null != model && "1".equals(type)) {
                Date dayTime = sdf.parse(executionTime);
                long timss = dayTime.getTime();
                Calendar calendar = Calendar.getInstance();
                for (int j = 0; j < 2; j++) {
        			/*RestTemplate restTemplate=new RestTemplate();
        			URI uri = util.getServiceUrl("paymentchannel", "error url request!");
        			String url = uri.toString() + "/v1.0/paymentchannel/spend/add";
        			MultiValueMap<String, String> requestEntity  = new LinkedMultiValueMap<String, String>();
        			requestEntity.add("status", "0");*/
                    timss -= (1800000 + (long) (Math.random() * 1800000));
                    calendar.setTimeInMillis(timss);
                    dayTime = calendar.getTime();
                    Object result;
                    if (j == 0) {
                        result = ss.addSpend(request, "0", String.valueOf(amountE), payCard, batchNo, userId, bindId, "", "", sdf.format(dayTime) + ":00", orderCode);
                        //requestEntity.add("amount", String.valueOf(amountE));
                    } else {
                        result = ss.addSpend(request, "0", decimalFormat.format(new BigDecimal(String.valueOf(amountEEE)).add(new BigDecimal(littleBalance + surplus))), payCard, batchNo, userId, bindId, "", "", sdf.format(dayTime) + ":00", orderCode);
                        //requestEntity.add("amount", decimalFormat.format(new BigDecimal(String.valueOf(amountEEE)).add(new BigDecimal(littlebalance+surplus))));
                    }
        			/*requestEntity.add("executionTime", sdf.format(dayTime)+":00");
        			requestEntity.add("payCard", payCard);
        			requestEntity.add("batchNo", batchNo);
        			requestEntity.add("bindId", creditCardTask.getBindId2());
        			requestEntity.add("userId", String.valueOf(creditCardTask.getUserId2()));
        			requestEntity.add("orderCode", order);
        			String result = restTemplate.postForObject(url, requestEntity, String.class);*/
                    JSONObject jobj = JSONObject.fromObject(result);
                    AutomaticRepaymentTaskService arts = new AutomaticRepaymentTaskService();
                    if (!jobj.containsKey("result") || jobj.getJSONObject("result").isEmpty()) {
                        result = arts.deleteAutomaticRepaymentTaskByOrderCode(orderCode);
        				/*restTemplate=new RestTemplate();
        				uri = util.getServiceUrl("paymentchannel", "error url request!");
        				url = uri.toString() + "/v1.0/paymentchannel/automaticrepaymenttask/delete/byordercode";
        				requestEntity  = new LinkedMultiValueMap<String, String>();
        				requestEntity.add("orderCode", order);
        				result = restTemplate.postForObject(url, requestEntity, String.class);*/
                        map.put(CommonConstants.RESP_CODE, CommonConstants.ERROR_PARAM);
                        map.put(CommonConstants.RESP_MESSAGE, "任务添加失败，请重试！");
                        return map;
                    }
                }
            }
        } catch (Exception e) {
            LOG.error(e.toString());
            map.put(CommonConstants.RESP_CODE, CommonConstants.ERROR_PARAM);
            map.put(CommonConstants.RESP_MESSAGE, "添加失败,操作数据库异常");
            return map;
        }

        map.put(CommonConstants.RESP_CODE, CommonConstants.SUCCESS);
        map.put(CommonConstants.RESULT, model);
        map.put(CommonConstants.RESP_MESSAGE, "添加成功");

        return map;
    }

    @RequestMapping(method = RequestMethod.POST, value = "/v1.0/paymentchannel/automaticrepaymenttask/findbyuserid")
    public @ResponseBody
    Object findByUserId(@RequestParam(value = "userId") String userId) {
        Map<String, Object> map = new HashMap<>();
        try {
            List<AutomaticRepaymentTask> list = automaticRepaymentTask.findByUserId(Integer.valueOf(userId.trim()));
            if (null == list || list.size() < 1) {
                map.put(CommonConstants.RESP_CODE, CommonConstants.FALIED);
                map.put(CommonConstants.RESP_MESSAGE, "没有数据");
            } else {
                map.put(CommonConstants.RESP_CODE, CommonConstants.SUCCESS);
                map.put(CommonConstants.RESP_MESSAGE, "查询成功");
                map.put(CommonConstants.RESULT, list);
            }
        } catch (Exception e) {
            // TODO: handle exception
            map.put(CommonConstants.RESP_CODE, CommonConstants.FALIED);
            map.put(CommonConstants.RESP_MESSAGE, e.getMessage());
        }
        return map;
    }

    @RequestMapping(method = RequestMethod.POST, value = "/v1.0/paymentchannel/automaticrepaymenttask/update")
    public @ResponseBody
    Object updateAutomaticRepaymentTask(
            @RequestParam(value = "orderCode") String orderCode, @RequestParam(value = "status") String status) {

        Map<String, Object> map = new HashMap<>();
        AutomaticRepaymentTask model = automaticRepaymentTask.findByOrderCode(orderCode);
        if (model == null) {
            map.put(CommonConstants.RESP_CODE, CommonConstants.FALIED);
            map.put(CommonConstants.RESP_MESSAGE, "无该订单记录,修改失败");
            return map;
        }
        model.setStatus(status);
        try {
            model = automaticRepaymentTask.updateType(model);
        } catch (Exception e) {
            LOG.error(e.toString());
            map.put(CommonConstants.RESP_CODE, CommonConstants.FALIED);
            map.put(CommonConstants.RESP_MESSAGE, "修改失败,操作数据库失败");
            return map;
        }

        map.put(CommonConstants.RESP_CODE, CommonConstants.SUCCESS);
        map.put(CommonConstants.RESP_MESSAGE, "修改status成功");
        map.put(CommonConstants.RESULT, model);
        return map;
    }

    @RequestMapping(method = RequestMethod.POST, value = "/v1.0/paymentchannel/automaticrepaymenttask/updatemoney")
    public @ResponseBody
    Object updateMoney(
            @RequestParam(value = "realAmount") String realAmount,
            @RequestParam(value = "amount") String amount,
            @RequestParam(value = "orderCode") String orderCode,
            @RequestParam(value = "status") String status) {

        Map<String, Object> map = new HashMap<>();
        AutomaticRepaymentTask model = automaticRepaymentTask.findByOrderCode(orderCode);
        if (model == null) {
            map.put(CommonConstants.RESP_CODE, CommonConstants.FALIED);
            map.put(CommonConstants.RESP_MESSAGE, "无该订单记录,修改失败");
            return map;
        }
        model.setStatus(status);
        model.setAmount(new BigDecimal(amount));
        model.setRealAmount(new BigDecimal(realAmount));
        try {
            model = automaticRepaymentTask.updateType(model);
        } catch (Exception e) {
            LOG.error(e.toString());
            map.put(CommonConstants.RESP_CODE, CommonConstants.FALIED);
            map.put(CommonConstants.RESP_MESSAGE, "修改失败,操作数据库失败");
            return map;
        }

        map.put(CommonConstants.RESP_CODE, CommonConstants.SUCCESS);
        map.put(CommonConstants.RESP_MESSAGE, "修改status成功");
        map.put(CommonConstants.RESULT, model);
        return map;
    }

    @RequestMapping(method = RequestMethod.POST, value = "/v1.0/paymentchannel/automaticrepaymenttask/find")
    public @ResponseBody
    Object findAutomaticRepaymentTask(
            @RequestParam(value = "start", required = false, defaultValue = "") String start,
            @RequestParam(value = "end", required = false, defaultValue = "") String end,
            @RequestParam(value = "type", required = false, defaultValue = "") String type,
            @RequestParam(value = "userId", required = false, defaultValue = "") String userid,
            @RequestParam(value = "bankNo", required = false, defaultValue = "") String bankNo,
            @RequestParam(value = "bindId", required = false, defaultValue = "") String bindId,
            // flag:0 表示status=0;1表示status=1,2,3,4;2表示查所有status记录
            @RequestParam(value = "flag", required = false, defaultValue = "") String flag) {
        Map<String, Object> map = new HashMap<>();

        if (hasText(start) && hasText(userid) && hasText(bindId)) {
            map.put(CommonConstants.RESP_CODE, CommonConstants.ERROR_PARAM);
            map.put(CommonConstants.RESP_MESSAGE, "不能同时传executionTime和userid");
            return map;
        }

        List<AutomaticRepaymentTask> models = null;
        Integer userId = null;
        if (hasText(userid)) {
            try {
                userId = Integer.valueOf(userid);
            } catch (NumberFormatException e1) {
                map.put(CommonConstants.RESP_CODE, CommonConstants.ERROR_PARAM);
                map.put(CommonConstants.RESP_MESSAGE, "userId只能为数字");
                return map;
            }
        }


        try {
            if (!"".equals(start) && !"".equals(end)) {
                // 根据executionTime查询
                models = automaticRepaymentTask.findByExecutionTime(start, end, type);
            } else if (hasText(bindId) && userId == null) {
                models = automaticRepaymentTask.findByBindId(bindId);
            } else if (hasText(bindId) && userId != null) {
                if (hasText(flag)) {
                    if ("0".equals(flag)) {
                        // 根据userId和status=0查询
                        models = automaticRepaymentTask.findByUserIdAndStatusA(userId, bindId);
						/*models2 = automaticRepaymentTask.findByUserIdAndStatusD(userId, bankNo);
						models.clear();
						models.addAll(models2);*/
                    } else if ("1".equals(flag)) {
                        // 根据userId和status!=0查询
                        models = automaticRepaymentTask.findByUserIdAndStatusB(userId, bindId);
						/*models2 = automaticRepaymentTask.findByUserIdAndStatusE(userId, bankNo);
						models.clear();
						models.addAll(models2);*/
                    } else if ("2".equals(flag)) {
                        // 只根据userId查询
                        models = automaticRepaymentTask.findByUserIdAndStatusC(userId, bindId);
                    } else {
                        map.put(CommonConstants.RESP_CODE, CommonConstants.ERROR_PARAM);
                        map.put(CommonConstants.RESP_MESSAGE, "flag参数错误,falg取值为0,1,2");
                        return map;
                    }
                } else {
                    // 只根据userId查询
                    models = automaticRepaymentTask.findByUserIdAndStatusC(userId, bindId);
                }
            }
        } catch (Exception ex) {
            LOG.error(ex.getMessage());
            map.put(CommonConstants.RESP_CODE, CommonConstants.ERROR_PARAM);
            map.put(CommonConstants.RESP_MESSAGE, "操作数据库失败,参数错误");
            return map;
        }

        if (models == null || models.size() == 0) {
            map.put(CommonConstants.RESP_CODE, CommonConstants.SUCCESS);
            map.put(CommonConstants.RESP_MESSAGE, "查询成功,无匹配记录");
            return map;
        }

        map.put(CommonConstants.RESP_CODE, CommonConstants.SUCCESS);
        map.put(CommonConstants.RESP_MESSAGE, "查询成功");
        map.put(CommonConstants.RESULT, models);
        return map;
    }

    @RequestMapping(method = RequestMethod.POST, value = "/v1.0/paymentchannel/automaticrepaymenttask/delete/byordercode")
    public @ResponseBody
    Object deleteAutomaticRepaymentTaskByOrderCode(
            @RequestParam(value = "orderCode") String orderCode
    ) {
        Map<String, Object> map = new HashMap<>();
        AutomaticRepaymentTask model;
        try {
            model = automaticRepaymentTask.findByOrderCode(orderCode);
        } catch (Exception e) {
            LOG.error(e.getMessage());
            map.put(CommonConstants.RESP_CODE, CommonConstants.FALIED);
            map.put(CommonConstants.RESP_MESSAGE, "服务器忙");
            return map;
        }
        if (model == null) {
            map.put(CommonConstants.RESP_CODE, CommonConstants.FALIED);
            map.put(CommonConstants.RESP_MESSAGE, "没有数据需要删除");
            return map;
        }
        try {
            if (model.getExecutionTime().getTime() - (new Date()).getTime() > 0 && model.getExecutionTime().getTime() - (new Date()).getTime() < 1000 * 60 * 60) {
                map.put(CommonConstants.RESP_CODE, CommonConstants.FALIED);
                map.put(CommonConstants.RESP_MESSAGE, "不能删除1小时内的待执行任务!");
                return map;
            } else if ((new Date()).getTime() - model.getExecutionTime().getTime() > 0 && (new Date()).getTime() - model.getExecutionTime().getTime() < 1000 * 60 * 60) {
                map.put(CommonConstants.RESP_CODE, CommonConstants.FALIED);
                map.put(CommonConstants.RESP_MESSAGE, "不能删除一小时内的历史任务!");
                return map;
            } else {
                automaticRepaymentTask.delete(model);
            }
        } catch (Exception e) {
            LOG.error(e.getMessage());
            map.put(CommonConstants.RESP_CODE, CommonConstants.FALIED);
            map.put(CommonConstants.RESP_MESSAGE, "服务器繁忙");
            return map;
        }
        map.put(CommonConstants.RESP_CODE, CommonConstants.SUCCESS);
        map.put(CommonConstants.RESP_MESSAGE, "删除任务成功");
        return map;

    }

    @RequestMapping(method = RequestMethod.POST, value = "/v1.0/paymentchannel/automaticrepaymenttask/find/byordercode")
    public @ResponseBody
    Object findAutomaticRepaymentTaskByOrderCode(
            @RequestParam(value = "orderCode") String orderCode) {
        Map<String, Object> map = new HashMap<>();
        AutomaticRepaymentTask model;
        try {
            model = automaticRepaymentTask.findByOrderCode(orderCode);
        } catch (Exception e) {
            LOG.error(e.getMessage());
            map.put(CommonConstants.RESP_CODE, CommonConstants.FALIED);
            map.put(CommonConstants.RESP_MESSAGE, "操作数据库查询异常");
            return map;
        }
        if (model == null) {
            map.put(CommonConstants.RESP_CODE, CommonConstants.FALIED);
            map.put(CommonConstants.RESP_MESSAGE, "无此orderCode记录");
            return map;
        }
        map.put(CommonConstants.RESP_CODE, CommonConstants.SUCCESS);
        map.put(CommonConstants.RESP_MESSAGE, "查询成功");
        map.put(CommonConstants.RESULT, model);
        return map;

    }


    @RequestMapping(method = RequestMethod.POST, value = "/v1.0/paymentchannel/automaticrepaymenttask/find/bypaycard")
    public @ResponseBody
    Object findAutomaticRepaymentTaskByPayCardAndTypeAndStatus(HttpServletRequest request,
                                                               @RequestParam(value = "time") String[] time,
                                                               @RequestParam(name = "payCard") String payCard,
                                                               @RequestParam(name = "type") String type
    ) {
        Map<String, Object> map = new HashMap<>();
        List<AutomaticRepaymentTask> models;
        List<NumberCheck> list = new ArrayList<>();
        String number;
        try {
            for (String aTime : time) {

                NumberCheck nc = new NumberCheck();
				/*SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd 00:00:00");
				SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd 23:59:59");*/
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

                Calendar c = Calendar.getInstance();
                c.setTimeInMillis((sdf.parse(aTime).getTime() + 86400000));
                String time2 = sdf.format(c.getTime());
                models = automaticRepaymentTask.findByPayCardAndStatus(aTime, time2, type, payCard);
                if (null == models) {
                    number = "1";
                } else {
                    number = String.valueOf(1 - models.size());
                }
                nc.setNumber(number);
                nc.setTime(aTime);
                nc.setType(type);
                list.add(nc);
            }
        } catch (Exception e) {
            LOG.error(e.getMessage());
            map.put(CommonConstants.RESP_CODE, CommonConstants.FALIED);
            map.put(CommonConstants.RESP_MESSAGE, "亲,出错了哟!请重试");
            return map;
        }
        map.put(CommonConstants.RESP_CODE, CommonConstants.SUCCESS);
        map.put(CommonConstants.RESP_MESSAGE, "查询成功了哦!");
        map.put(CommonConstants.RESULT, list);
        return map;
    }

    @RequestMapping(method = RequestMethod.POST, value = "/v1.0/paymentchannel/automaticrepaymenttask/queryTaskByBatchNo")
    public @ResponseBody
    Object queryAutomaticByBatch(
            @RequestParam(value = "batchNo") String batchNo) {
        Map<String, Object> map = new HashMap<>();


        try {
            List<AutomaticRepaymentTask> task = automaticRepaymentTask.queryAutomaticByBatchNo(batchNo);
            if (task.isEmpty()) {
                map.put(CommonConstants.RESP_CODE, CommonConstants.FALIED);
                map.put(CommonConstants.RESP_MESSAGE, "查询有误");
            } else {
                map.put(CommonConstants.RESP_CODE, CommonConstants.SUCCESS);
                map.put(CommonConstants.RESP_MESSAGE, "查询成功");
                map.put(CommonConstants.RESULT, task);
            }

        } catch (Exception ex) {
            LOG.error(ex.getMessage());
            map.put(CommonConstants.RESP_CODE, CommonConstants.FALIED);
            map.put(CommonConstants.RESP_MESSAGE, "查询有误");
        }

        return map;
    }
}
